<?php


namespace app\common\service;


use broadcast\redis\RedisService;
use Hedeqiang\TenIM\IM;
use Tencent\TLSSigAPIv2;
use think\Exception;
use broadcast\redis\setRedis;
use app\models\system\SystemWebsite;


class TenImService
{
    //IM实例化对象
    private static $IM = null;

    private static $config = [
        'sdk_app_id' => '',
        'identifier' => '',
        'secret_key' => '',
    ];

    private static function initialize()
    {

        $low_config = setRedis::getCache( session('website'), "info");
        if ($low_config) {
            self::$config['sdk_app_id'] = $low_config['tencent_appid'];
            self::$config['identifier'] = $low_config['tencent_username'];
            self::$config['secret_key'] = $low_config['tencent_password'];
        }
        self::$IM = new IM(self::$config);
    }

    /**
     * 获取基本信息
     * @param $roomid
     * @param $user
     * @return array
     */
    public static function getSettings($rid, $user)
    {
        $website = session('website');
        if (!$website) {
            throw new \think\Exception('未获取到网站标识!');
        }

        // 获取房间ID
        $roomId = self::initRoom();

        $params = self::getAccount($rid, $user);

        $userSig = self::getUserSig($params);

        // 初始化用户进入房间的昵称
//        self::setUserProfile([
//            'From_Account' => $params['Identifier'],
//            'ProfileItem' => [
//                ['Tag' => 'Tag_Profile_IM_Nick', 'Value' => $params['Nick']]
//            ]
//        ]);


        // 获取房间互通规则
        $roomGroup = getNowInterWork(session('website'), $rid);

        $userID = $params['Identifier'];

        //设置用户信息
        $setUser = array();
        //获取群组名称
        $low_config = setRedis::getCache($website, "info");
        if ($low_config) {
            $config = $low_config;
        } else {
            $config = SystemWebsite::where("website_ident", $website)->find();
            if ($config) {
                $config = $config->toArray();
                setRedis::setCache($website, 'info', $config, 0);
            }
        }

        $iserInfos = ['GroupId' => $config['chat'], 'Member_Account' => $userID];
        if ($user['group'] == 1 || $user['group'] == 5 || $user['group'] == 6) {
            $iserInfos['Role'] = 'Admin';
        } else {
            $iserInfos['Role'] = 'Member';
        }
        self::modifyGroupMemberInfo($iserInfos);
        //设置群信息  end

        return compact('roomId', 'userID', 'userSig', 'roomGroup','params');
    }

    /**
     * 初始化房间
     * @param $roomid
     * @return bool
     */
    public static function initRoom ()
    {
        // TODO redis 缓存
        $website = session('website');
        $roomId = "@{$website}";
        self::initialize();
        $params = [
            'GroupIdList' => [
                $roomId
            ]
        ];

        // 群存在
        $res = self::$IM->send('group_open_http_svc', 'get_group_info', $params);

        if ($res['ErrorCode'] == 0 && $res['GroupInfo'][0]['ErrorCode'] == 0) {
            return $roomId;
        }

        //不存在创建
        $res = self::createGroup();
        if ($res['ErrorCode'] == 0) {
            return $roomId;
        }
        return false;
    }


    /**
     * 获取用户UserSig
     */
    public static function getUserSig($params)
    {

        $redis = new RedisService(config('cache')['stores']['single']);

        $userSigkey = 'imUser:' . $params['Identifier'];

//        $userSig = $redis->hGet($userSigkey, 'SigKey');

        self::initialize();
        $userSig = (new TLSSigAPIv2(self::$config['sdk_app_id'], self::$config['secret_key']))->genSig($params['Identifier']);
        $redis->hMset($userSigkey, ['SigKey' => $userSig, 'Nick' => $params['Nick']]);

        // 导入用户，并生成
//        if (!$userSig) {
//            $res = self::importAccount($params);
//            if ($res['ActionStatus'] == 'OK') {
//                $userSig = (new TLSSigAPIv2(self::$config['sdk_app_id'], self::$config['secret_key']))->genSig($params['Identifier']);
//                $redis->hMset($userSigkey, ['SigKey' => $userSig, 'Nick' => $params['Nick']]);
//            }
//        }else{
//            // todo 如果更换了IM账户，执行清空UserSig,就不需要了
//            self::initialize();
//            $userSig = (new TLSSigAPIv2(self::$config['sdk_app_id'], self::$config['secret_key']))->genSig($params['Identifier']);
//            $redis->hMset($userSigkey, ['SigKey' => $userSig, 'Nick' => $params['Nick']]);
//        }
        return $userSig;
    }

    /**
     * 导入用户
     * @param $params
     * @return mixed
     */
    public static function importAccount($params)
    {
        self::initialize();
        try {
            return self::$IM->send('im_open_login_svc', 'account_import', $params);
        } catch (\Exception $e) {
            $res = str_replace('Tim REST API error: ', '', $e->getMessage());
            $res = json_decode($res, true);
            throw new \think\Exception($res['ErrorInfo'], $res['ErrorCode']);
        }
    }

    /**
     * 设置用户资料
     * @param $params
     * @return mixed
     * @throws Exception
     */
    public static function setUserProfile($params)
    {
        self::initialize();
        try {
            return self::$IM->send('profile', 'portrait_set', $params);
        } catch (\Exception $e) {
            $res = str_replace('Tim REST API error: ', '', $e->getMessage());
            $res = json_decode($res, true);
            throw new \think\Exception($res['ErrorInfo'], $res['ErrorCode']);
        }

    }

    /**
     * 创建群
     * @param $roomid 群ID
     * @param string $Owner_Account 群主账户
     * @param null $params 自定义群类型
     * @return mixed
     */
    public static function createGroup($Owner_Account = '', $params = null)
    {
        $website = session('website');
        if (!$params) {
            $params = [
                "Owner_Account" => $Owner_Account,
                "Type" => 'AVChatRoom',
                "GroupId" => "@{$website}",
                "Name" => "@{$website}"
            ];
        }

        try {
            return self::$IM->send('group_open_http_svc', 'create_group', $params);
        } catch (\Exception $e) {
            $res = str_replace('Tim REST API error: ', '', $e->getMessage());
            $res = json_decode($res, true);
            throw new \think\Exception($res['ErrorInfo'], $res['ErrorCode']);
        }
    }

    /**
     * 获取群详情
     * @param $params
     * @return mixed
     */
    public static function getGroupInfo($params)
    {
        $params = [
            'GroupIdList' => [
                '@TGS#1NVTZEAE4',
                '@TGS#1CXTZEAET',
            ]
        ];
        try {
            return self::$IM->send('group_open_http_svc', 'get_group_info', $params);
        } catch (\Exception $e) {
            $res = str_replace('Tim REST API error: ', '', $e->getMessage());
            $res = json_decode($res, true);
            throw new \think\Exception($res['ErrorInfo'], $res['ErrorCode']);
        }
    }

    /**
     * 批量禁言和取消禁言
     * @param $params
     * @return mixed
     * @throws \think\Exception
     */
    public static function forbidSendMsg($params)
    {
        try {
            self::initialize();
            return self::$IM->send('group_open_http_svc', 'forbid_send_msg', $params);
        } catch (\Exception $e) {
            $res = str_replace('Tim REST API error: ', '', $e->getMessage());
            $res = json_decode($res, true);
            throw new \think\Exception($res['ErrorInfo'], $res['ErrorCode']);
        }
    }

    /**
     * 获取禁言列表
     * @param $params
     * @return mixed
     * @throws \think\Exception
     */
    public static function getGroupShuttedUin($params)
    {
        try {
            self::initialize();
            return self::$IM->send('group_open_http_svc', 'get_group_shutted_uin', $params);
        } catch (\Exception $e) {
            $res = str_replace('Tim REST API error: ', '', $e->getMessage());
            $res = json_decode($res, true);
            throw new \think\Exception($res['ErrorInfo'], $res['ErrorCode']);
        }
    }

    /**
     * 拉取群历史消息
     * @param string $GroupId 群组id
     * @param int $number 消息数量  最大 20
     */
    public static function getGroupMsgGetSimple($GroupId, $number)
    {
        $params = [
            'GroupId' => $GroupId,
            'ReqMsgNumber' => $number
        ];
        try {
            self::initialize();
            //获取基础数据
            $result = self::$IM->send('group_open_http_svc', 'group_msg_get_simple', $params);
            $data = array();
            //处理数据
            if (isset($result['ActionStatus']) && $result['ActionStatus'] == 'OK') {
                $data['msg'] = "获取历史成功";
                $data['status'] = 200;
                $data['GroupId'] = $result['GroupId'];
                $data['history'] = $result['RspMsgList'];
                return $data;
            } else {
                return ['msg' => "获取历史失败", 'status' => 400];

            }

        } catch (\Exception $e) {
            $res = str_replace('Tim REST API error: ', '', $e->getMessage());
            $res = json_decode($res, true);
            throw new \think\Exception($res['ErrorInfo'], $res['ErrorCode']);
        }
    }

    /**
     * 获取直博群在线人数
     * @param string $GroupId 群组id
     */
    public static function getOnlineMemberNum($GroupId)
    {
        $params = [
            "GroupId" => $GroupId
        ];
        try {
            self::initialize();
            $result = self::$IM->send('group_open_http_svc', 'get_online_member_num', $params);
            if (isset($result['ActionStatus']) && $result['ActionStatus'] == "OK") {
                $data = array();
                $data['msg'] = "获取群组人数成功";
                $data['status'] = 200;
                $data['GroupId'] = $result['GroupId'];
                $data['online_num'] = $result['OnlineMemberNum'];
                return $data;
            } else {
                return ['msg' => '获取群组人数失败', 'status' => 400];
            }
        } catch (\Exception $e) {
            $res = str_replace('Tim REST API error: ', '', $e->getMessage());
            $res = json_decode($res, true);
            throw new \think\Exception($res['ErrorInfo'], $res['ErrorCode']);
        }
    }

    /**
     * 设置全局禁言
     * @param string $account 用户标识
     */
    public static function setOnSpeaking($account, $singleChat = null, $groupChat = null)
    {
        $params = [
            'Set_Account' => $account,
        ];
        if ($singleChat != null) {
            $params['C2CmsgNospeakingTime'] = $singleChat != 'long' ? $singleChat : 4294967295;
        }
        if ($singleChat != null) {
            $params['GroupmsgNospeakingTime'] = $groupChat != 'long' ? $groupChat : 4294967295;
        }

        try {
            self::initialize();
            $result = self::$IM->send('openconfigsvr', 'setnospeaking', $params);
            if ($result['ErrorCode'] == 0) {
                return ['msg' => '禁言成功', 'status' => 200];
            } else {
                return ['msg' => '禁言失败', 'status' => 400];
            }
        } catch (\Exception $e) {
            $res = str_replace('Tim REST API error: ', '', $e->getMessage());
            $res = json_decode($res, true);
            throw new \think\Exception($res['ErrorInfo'], $res['ErrorCode']);
        }

    }

    /**
     * 查询全局禁言
     * @param string $account 用户标识
     */
    public static function getNoSpeakingList($account)
    {
        $params = ['Get_Account' => $account];
        try {
            self::initialize();
            $result = self::$IM->send('openconfigsvr', 'getnospeaking', $params);
            if ($result['ErrorCode'] == 0) {
                return ['msg' => '获取信息成功', 'status' => 200, 'C2CmsgNospeakingTime' => $result['C2CmsgNospeakingTime'], 'GroupmsgNospeakingTime' => $result['GroupmsgNospeakingTime']];
            } else {
                return ['msg' => '获取信息失败', 'status' => 400];
            }
        } catch (\Exception $e) {
            $res = str_replace('Tim REST API error: ', '', $e->getMessage());
            $res = json_decode($res, true);
            throw new \think\Exception($res['ErrorInfo'], $res['ErrorCode']);
        }
    }

    /**
     * 查看账号
     * @param array $userList 用户id 列表
     */
    public static function searchAccountCheck($userList)
    {
        $params = [
            "CheckItem" => array()
        ];

        foreach ($userList as $item) {
            $params['CheckItem'][] = ['UserID' => $item];
        }
        try {
            self::initialize();
            $result = self::$IM->send('im_open_login_svc', 'account_check', $params);
            if (isset($result['ActionStatus'])) {
                if ($result['ActionStatus'] == "OK") {
                    return ['msg' => '获取信息成功', 'status' => 200, 'userList' => $result['ResultItem']];
                } else {
                    return ['msg' => '获取信息失败', 'status' => 400];
                }
            } else {
                return ['msg' => '获取信息失败', 'status' => 400];
            }
        } catch (\Exception $e) {
            $res = str_replace('Tim REST API error: ', '', $e->getMessage());
            $res = json_decode($res, true);
            throw new \think\Exception($res['ErrorInfo'], $res['ErrorCode']);
        }
    }

    /**
     * 获取账号在线状态
     * @param array $userList 用户列表
     */
    public static function getQueryStates($userList, $type = 0)
    {
        $params = [
            'To_Account' => $userList
        ];

        if ($type != 0) {
            $params['IsNeedDetail'] = 1;
        }

        try {
            self::initialize();
            $result = self::$IM->send("openim", 'querystate', $params);
            if (isset($result['ActionStatus'])) {
                if ($result['ActionStatus'] == "OK") {
                    return ['msg' => '获取信息成功', 'status' => 200, 'userList' => $result['QueryResult'], 'failList' => $result['ErrorList']];
                } else {
                    return ['msg' => '获取信息失败', 'status' => 400];
                }
            } else {
                return ['msg' => '获取信息失败', 'status' => 400];
            }
        } catch (\Exception $e) {
            $res = str_replace('Tim REST API error: ', '', $e->getMessage());
            $res = json_decode($res, true);
            throw new \think\Exception($res['ErrorInfo'], $res['ErrorCode']);
        }
    }

    /**
     * 获取群成员
     * @param array $params
     * @return mixed
     * @throws Exception
     */
    public static function getGroupMemberInfo(array $params)
    {
        try {
            self::initialize();
            return self::$IM->send("group_open_http_svc", 'get_group_member_info', $params);
        } catch (\Exception $e) {
            $res = str_replace('Tim REST API error: ', '', $e->getMessage());
            $res = json_decode($res, true);
            throw new \think\Exception($res['ErrorInfo'], $res['ErrorCode']);
        }
    }

    /**
     * 修改群成员资料
     * @param array $params
     * @return mixed
     * @throws Exception
     */
    public static function modifyGroupMemberInfo(array $params)
    {
        try {
            self::initialize();
            return self::$IM->send("group_open_http_svc", 'modify_group_member_info', $params);
        } catch (\Exception $e) {
            $res = str_replace('Tim REST API error: ', '', $e->getMessage());
            $res = json_decode($res, true);
            throw new \think\Exception($res['ErrorInfo'], $res['ErrorCode']);
        }
    }

    /**
     * 获取群ID
     * @return string
     */
    public static function getGroupId()
    {
        $website = session('website');
        return "@{$website}";
    }

    /**
     * 获取账户
     * @param $rid
     * @param $user
     * @return string
     */
    public static function getAccount($rid, $user)
    {
        // _W_网站标识_U_用户昵称_X_用户权限
        $Identifier = '_W_' . session('website') . '_U_' . $user['username'];

        // _W_网站标识_R_房间ID_U_用户昵称_X_用户权限
        $Nick = '_W_' . session('website') . '_R_' . $rid . '_U_' . $user['username'] . '_X_' . $user['group'];
        $FaceUrl = $user['portrait'] ?? '';
        return compact('Identifier', 'Nick', 'FaceUrl');
    }

    /**
     * 获取用户资料
     * @param $user
     * @return mixed
     * @throws Exception
     */
    public static function getImAccount ($user) {
        try {
            $params = [
                'To_Account' => $user,
                'TagList' => ['Tag_Profile_IM_Nick']
            ];
            self::initialize();
            return self::$IM->send("profile", 'portrait_get', $params);
        } catch (\Exception $e) {
            $res = str_replace('Tim REST API error: ', '', $e->getMessage());
            $res = json_decode($res, true);
            if ($res) {
                throw new \think\Exception($res['ErrorInfo'], $res['ErrorCode']);
            }
            throw new Exception($e->getMessage());
        }
    }
}